﻿using System;
using System.Reflection;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Threading;

namespace mlnx_os_sysdump_analyzer
{
    public partial class MDIParent : Form
    {
        private int childFormNumber = 0;
        private int tabNum = 0;
        private object childFormNumberLOCK = new Object();
        private bool mainFormClosing = false;
        //
        //----------------------------------------------------
      
        /// <summary>
        /// add event handler to AssemblyResolve in order to load the dll file which were embedded inside the applications .exe file.
        /// </summary>
        [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
        public MDIParent()
        {
            // load dll
            AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
            {
                string resourceName = new AssemblyName(args.Name).Name + ".dll";
                string resource = Array.Find(this.GetType().Assembly.GetManifestResourceNames(), element => element.EndsWith(resourceName));
                if (resource != null)
                {
                    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource))
                    {
                        Byte[] assemblyData = new Byte[stream.Length];
                        stream.Read(assemblyData, 0, assemblyData.Length);
                        return Assembly.Load(assemblyData);
                    }
                }
                else
                {
                    return null;
                } 
            };

            InitializeComponent();
            this.Text += " - " + ProductVersion;
            MarkerList.InitMarkers();
            
            ShowNewForm();
        }
        //
        //----------------------------------------------------
        //
       
        protected override void OnMdiChildActivate(EventArgs e)
        {
            base.OnMdiChildActivate(e);

            typeof(Form).InvokeMember("FormerlyActiveMdiChild",
                BindingFlags.Instance | BindingFlags.SetProperty |
                BindingFlags.NonPublic, null, this, new object[] { null });
        }
        //
        //----------------------------------------------------
      
        /// <summary>
        /// create a new window and its tab.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private Form1 ShowNewForm()
        {
            /// update the number of the live childs.
            childFormNumber++;
            /// update the tab's number
            tabNum++;
            /// create a new window
            Form1 childForm = new Form1("Tab " + tabNum);
            childForm.Text = "Tab " + tabNum;
            /// set the mdi parent
            childForm.MdiParent = this;
            childForm.mdiParentPtr = this;
            childForm.Size = this.Size;
            childForm.hideDockPanel();
            childForm.FormClosing += childForm_FormClosing;
            childForm.TextChanged += childForm_TextChanged;
            /// set the status label.
            toolStripStatusLabel.Text = childForm.Text;
            /// add a new tab
            TabPage tb = new TabPage("Tab " + tabNum);
            childForm.Tag = tb;
            tb.Tag = childForm;
            windowsTabs.TabPages.Add(tb);
            windowsTabs.SelectedTab = tb;
            /// show the window in maximized state
            childForm.Show();
            childForm.WindowState = FormWindowState.Maximized;

            return childForm; 
        }
        //
        //----------------------------------------------------
      
        /// <summary>
        /// update the status label and main form's title
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void childForm_TextChanged(object sender, EventArgs e)
        {
            try
            {
                Form1 f1 = (Form1)windowsTabs.SelectedTab.Tag;
                toolStripStatusLabel.Text = f1.Text;
                string[] name = Regex.Split(f1.Text, @"\\");
                windowsTabs.SelectedTab.Text = name[name.Length - 1];
            }
            catch { }

        }
        //
        //----------------------------------------------------
      
        /// <summary>
        /// close the window and remove its tab.
        /// if that was the last one, then open a new window.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void childForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                /// get the form that is closing
                Form f1 = sender as Form;
                if ((TabPage)f1.Tag != null)
                {
                    /// remove the tab
                    TabPage tp = (TabPage)f1.Tag;
                    try
                    {
                        tp.Tag = null;
                        windowsTabs.TabPages.Remove(tp);
                    }
                    catch { }
                }
                /// update the number of the live childs
                lock (childFormNumberLOCK)
                {
                    childFormNumber--;
                }
                /// if we are not closing the main application, and there no live child forms, then open a new one.
                if (childFormNumber == 0 && !mainFormClosing)
                {
                    tabNum = Int32.Parse(Regex.Split(f1.Text, " ")[1]);
                    tabNum--;
                    ShowNewForm();
                }
                /// remove the event handlers
                f1.FormClosing -= childForm_FormClosing;
                f1.TextChanged -= childForm_TextChanged;
                f1.MdiParent = null;
            }
            catch
            { }
        }      
        //
        //----------------------------------------------------
        //
        private void TileHorizontalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.TileHorizontal);
        }
        //
        //----------------------------------------------------
        //
        private void ArrangeIconsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.ArrangeIcons);
        }
        //
        //----------------------------------------------------
        //
        private void CloseAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            closeAll();
        }
        //
        //----------------------------------------------------
       
        /// <summary>
        /// update the main window's title and the status label with the title of the current active child.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void windowsTabs_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (windowsTabs.SelectedTab != null)
            {
                Form f1 = (Form1)windowsTabs.SelectedTab.Tag;
                f1.WindowState = FormWindowState.Maximized;
                toolStripStatusLabel.Text = f1.Text;
                f1.Activate();
                f1.Focus();
            }
        }
        //
        //----------------------------------------------------
        //
        private void newToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            ShowNewForm();
        }
        //
        //----------------------------------------------------
        //
        private void closeAllToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            closeAll();
        }
        //
        //----------------------------------------------------
       
        /// <summary>
        /// close the application.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            mainFormClosing = true;
            closeAll();
            Environment.Exit(0);
        }
        //
        //----------------------------------------------------
        //
        private void closeAll()
        {
            foreach (Form childForm in MdiChildren)
            {
                childForm.Close();
            }
        }
        //
        //----------------------------------------------------
        //
        private void MDIParent_FormClosing(object sender, FormClosingEventArgs e)
        {
            mainFormClosing = true;
            closeAll();
            Environment.Exit(0);
        }
        //
        //----------------------------------------------------
       
        /// <summary>
        /// search for the keyword in the current active child form.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void searchToolStripButton_Click(object sender, EventArgs e)
        {
            Form1 f1 = (Form1)windowsTabs.SelectedTab.Tag;
            if (f1.searchInCurrentTab(keywordToolStripTextBox.Text) == false)
            {
                searchNoteToolStripLabel.Text = "Can't find this keyword!";
            }
            else
            {
                searchNoteToolStripLabel.Text = "";
            }
        }
        //
        //----------------------------------------------------
        
        /// <summary>
        /// search for the keyword in the current active child form.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void keywordToolStripTextBox_Click(object sender, EventArgs e)
        {
            searchNoteToolStripLabel.Text = "";
            if (keywordToolStripTextBox.Text.Equals("type here to search"))
            {
                keywordToolStripTextBox.Text = "";
            }
        }
        //
        //----------------------------------------------------
       
        /// <summary>
        /// reset the text inside the keyword text box.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void keywordToolStripTextBox_Leave(object sender, EventArgs e)
        {
            searchNoteToolStripLabel.Text = "";
            if (keywordToolStripTextBox.Text.Equals(""))
            {
                keywordToolStripTextBox.Text = "type here to search";
            }
        }
        //
        //----------------------------------------------------
        
        /// <summary>
        /// clear  the text of the keyword text box.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void clearToolStripButton1_Click(object sender, EventArgs e)
        {
            Form1 f1 = (Form1)windowsTabs.SelectedTab.Tag;
            f1.resetBgColorForSelections();
            keywordToolStripTextBox.Text = "type here to search";
            searchNoteToolStripLabel.Text = "";
        }
        //
        //----------------------------------------------------
        
        /// <summary>
        /// event handler for hitting enter --> start the search.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void keywordToolStripTextBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                searchToolStripButton_Click(null, null);
            }
        }
        //
        //----------------------------------------------------
        //
        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            Form1 f1 = (Form1)windowsTabs.SelectedTab.Tag;
            f1.Close();
        }
        //
        //----------------------------------------------------
        //
        private void ExitToolsStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void CutToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        
        private void CascadeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.Cascade);
        }

        private void TileVerticalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.TileVertical);
        }
        
        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void ToolBarToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void StatusBarToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
        //
        //----------------------------------------------------
        
        /// <summary>
        /// make sure the logo is displayed correctly in the menu strip.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void menuStrip_ItemAdded(object sender, ToolStripItemEventArgs e)
        {
            if (e.Item.Text == "")
            {
                e.Item.Image = this.Icon.ToBitmap();
                e.Item.ImageScaling = ToolStripItemImageScaling.SizeToFit;
            }
        }
        //
        //----------------------------------------------------
        
        /// <summary>
        /// show the about form.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (new AboutBox()).ShowDialog();
        }
        //
        //----------------------------------------------------
        
        /// <summary>
        /// open a file in the current active form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //Form1 f1 = (Form1)windowsTabs.SelectedTab.Tag;
            //f1.openFileDialog();
            openFilesDialog();
        }
        //
        //----------------------------------------------------

        /// <summary>
        /// show open multiple files dialog
        /// </summary>
        public void openFilesDialog()
        {
            try
            {
                OpenFileDialog of = new OpenFileDialog();
                of.Multiselect = true; // allow selecting multiple files
                of.Filter = "All Files|*.*";
                if (of.ShowDialog() == DialogResult.OK)
                {
                    openFilesInTabs(of.FileNames);
                }
            }
            catch
            {
            }
        }
        //
        //----------------------------------------------------

        /// <summary>
        /// open files, each one in a unique tab.
        /// </summary>
        /// <param name="fileNames"></param>
        private void openFilesInTabs(string[] fileNames)
        {
            int ii = 0;
            /// if we have one tab opened, check if there is a file loaded,
            /// if no file is loaded, then load the first file to this tab
            /// otherwise, load it in a new tab.
            Form1 f1 = (Form1)windowsTabs.SelectedTab.Tag;
            if (f1.isClear)
            {
                // load it to this tab
                f1.fileHandler(fileNames[0]);
                ii++;
            }
            // load the rest in new tabs.
            for (; ii < fileNames.Length; ii++)
            {
                if (fileNames[ii] != "")
                {
                    Form1 ff1 = ShowNewForm();
                    ff1.fileHandler(fileNames[ii]);
                }
            }
        }

        /// <summary>
        /// stop and clear the current active form.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void clearToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form1 f1 = (Form1)windowsTabs.SelectedTab.Tag;
            f1.stopAndClear();
        }
        //
        //----------------------------------------------------
        /// <summary>
        /// close the current active form.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form1 f1 = (Form1)windowsTabs.SelectedTab.Tag;
            f1.stopAndClear();
            f1.Close();
        }
        //
        //----------------------------------------------------
        
        /// <summary>
        /// open file in the current active form.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void openToolStripButton_Click(object sender, EventArgs e)
        {
            //Form1 f1 = (Form1)windowsTabs.SelectedTab.Tag;
            //f1.openFileDialog();
            openFilesDialog();
        }
        
        //
        //----------------------------------------------------
        /// <summary>
        /// select the relevant tab for the current active form.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MDIParent_MdiChildActivate(object sender, EventArgs e)
        {
            try
            {
                if (ActiveMdiChild != null)
                {
                    Form activeChild = this.ActiveMdiChild;
                    windowsTabs.SelectedTab = (TabPage)activeChild.Tag;
                }
            }
            catch { }
        }
       
        //
        //----------------------------------------------------
        /// <summary>
        /// show the settings panel
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void preferencesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Settings sett = new Settings();
            sett.ShowDialog();
            if (sett.dialogResult == System.Windows.Forms.DialogResult.OK)
            {
                // apply new font to all open windows (in case it was changed) -> this should run only if the user clicked OK.
                foreach (Form1 childForm in MdiChildren)
                {
                    (new Thread(new ThreadStart(childForm.refresh))).Start();
                    //childForm.refresh();
                }
            }
        }
        
        //
        //----------------------------------------------------
        /// <summary>
        /// show the fond dialog
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void styleConfiguratorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                FontDialog fd = new FontDialog();
                fd.Font = Properties.Settings.Default.myFont;
                if (fd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    // save the new font
                    Properties.Settings.Default.myFont = fd.Font;
                    Properties.Settings.Default.Save();

                    // apply to all open windows
                    foreach (Form1 childForm in MdiChildren)
                    {
                        (new Thread(new ThreadStart(childForm.setFontForAll))).Start();
                        //childForm.setFontForAll();
                    }
                }
            }
            catch { }
        }
        
        //
        //----------------------------------------------------
        /// <summary>
        /// go to the Redmine project of the application
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void redmineToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Methods.RunProcess("http://redmine.mtl.com/projects/mosa/issues/new");
        }
        
        //
        //----------------------------------------------------
        /// <summary>
        /// go to Sales Force.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void salesForceToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Methods.RunProcess("https://na3.salesforce.com/home/home.jsp");
        }
        
        //
        //----------------------------------------------------
        /// <summary>
        /// go to support web portal
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mellanoxSupportPortalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Methods.RunProcess("http://support.mellanox.com/SupportWeb");
        }
        
        //
        //----------------------------------------------------
        /// <summary>
        /// undock the current active form.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void unDockTabButton_Click(object sender, EventArgs e)
        {
            try
            {
                /// get the current active form.
                Form1 f1 = (Form1)windowsTabs.SelectedTab.Tag;
                /// remove its tab
                TabPage tp = (TabPage)f1.Tag;
                try
                {
                    tp.Tag = null;
                    windowsTabs.TabPages.Remove(tp);
                }
                catch { }
                /// update the number of active childs
                lock (childFormNumberLOCK)
                {
                    childFormNumber--;
                }
                if (childFormNumber == 0)
                {
                    tabNum = Int32.Parse(Regex.Split(f1.Text, " ")[1]);
                    ShowNewForm();
                }
                /// remove the event handlers
                f1.FormClosing -= childForm_FormClosing;
                f1.TextChanged -= childForm_TextChanged;
                /// undock the form
                f1.unDockTab();
            }
            catch
            { }
        }
        
        //
        //----------------------------------------------------
        /// <summary>
        /// dock the an existing form (that was undocked earlier).
        /// </summary>
        /// <param name="childForm"></param>
        public void addExistingChildForm(Form1 childForm)
        {
            try
            {
                if (childForm == null)
                    return;
                childFormNumber++;

                childForm.MdiParent = this;
                toolStripStatusLabel.Text = childForm.Text;
                childForm.Size = this.Size;

                childForm.FormClosing += childForm_FormClosing;
                childForm.TextChanged += childForm_TextChanged;

                //TabPage tb = new TabPage("Tab " + Int32.Parse(Regex.Split(childForm.Text, " ")[1]));
                string[] name = Regex.Split(childForm.Text, @"\\");
                TabPage tb = new TabPage(name[name.Length - 1]);
                childForm.Tag = tb;
                tb.Tag = childForm;
                windowsTabs.TabPages.Add(tb);
                windowsTabs.SelectedTab = tb;
                childForm.hideDockPanel();
                childForm.WindowState = FormWindowState.Maximized;
            }
            catch { }
        }

        //
        //----------------------------------------------------
        //
        private void newToolStripButton_Click(object sender, EventArgs e)
        {
            ShowNewForm();
        }

        //
        //----------------------------------------------------
        //
        private void MDIParent_DragDrop(object sender, DragEventArgs e)
        {
            try
            {
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    string[] filePaths = (string[])(e.Data.GetData(DataFormats.FileDrop));
                    openFilesInTabs(filePaths);
                }
            }
            catch
            { }
        }

        //
        //----------------------------------------------------
        //
        private void MDIParent_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }
        //
        //----------------------------------------------------
        //

        private void MDIParent_DragLeave(object sender, EventArgs e)
        {

        }
        //
        //----------------------------------------------------
        //
        private void MDIParent_DragOver(object sender, DragEventArgs e)
        {

        }
        //
        //----------------------------------------------------
        //
        
        
    }
}
       
        
            